package wx

import (
	"encoding/json"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	core "github.com/chanxuehong/wechat.v2/mp/core"
	material "github.com/chanxuehong/wechat.v2/mp/material"
	menu "github.com/chanxuehong/wechat.v2/mp/menu"
	mass "github.com/chanxuehong/wechat.v2/mp/message/mass"
	mass2all "github.com/chanxuehong/wechat.v2/mp/message/mass/mass2all"
	//	models "mywechat/models"
	preview "github.com/chanxuehong/wechat.v2/mp/message/mass/preview"
)

var wechatClientMap = make(map[int64]*core.Client)

//var (
//	accessTokenServer core.AccessTokenServer = core.NewDefaultAccessTokenServer(beego.AppConfig.String("wxAppId"), beego.AppConfig.String("wxAppSecret"), nil)
//	wechatClient      *core.Client           = core.NewClient(accessTokenServer, nil)
//)

type WXController struct {
	BaseController
}
type Img struct {
	Filepath string
	Url      string
}
type Imgslice struct {
	Imgs []Img
}

func (this *WXController) MenuCreate() {
	//	btnSubA := []menu.Button{{Name: "组工政务", Type: "click", Key: "zgzw"}, {Name: "最新微讯", Type: "view", URL: "http://www.baidu.com"}}
	//	btnA := menu.Button{Name: "微组工", SubButtons: btnSubA}
	//	btns := []menu.Button{btnA}
	cid, err := this.GetInt64("cid")
	out := make(map[string]interface{})
	out["status"] = MSG_OK
	if err != nil {
		beego.Error("post request company id error is ", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = err
		this.jsonResult(out)
	}
	btns := []menu.Button{}
	var maps []orm.Params
	o := orm.NewOrm()
	_, errOrm := o.QueryTable("menu").Filter("CompanyId", cid).Filter("IsTop__exact", 0).Filter("CompanyId", cid).Values(&maps)
	if errOrm != nil {
		this.Ctx.WriteString(errOrm.Error())
		this.StopRun()
	}
	if len(maps) == 0 {
		beego.Error("menu is null  ", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = "menu is null"
		this.jsonResult(out)
	}
	for _, m := range maps {
		btn := menu.Button{MediaId: strconv.Itoa(int(m["Id"].(int64))), Name: m["Name"].(string), Type: m["Type"].(string), Key: m["Key"].(string), URL: m["Url"].(string)}
		btns = append(btns, btn)
	}
	for key, m := range btns {
		var mapsBtn []orm.Params
		_, e := o.QueryTable("menu").Filter("IsTop__exact", m.MediaId).Values(&mapsBtn)
		if e != nil {
			this.Ctx.WriteString(e.Error())
			this.StopRun()
		}
		for _, mbtn := range mapsBtn {
			btn := menu.Button{Name: mbtn["Name"].(string), Type: mbtn["Type"].(string), Key: mbtn["Key"].(string), URL: mbtn["Url"].(string)}
			btns[key].SubButtons = append(btns[key].SubButtons, btn)
		}
	}

	ms := menu.Menu{Buttons: btns}
	err = menu.Create(wechatClientMap[cid], &ms)

	if err != nil {
		log.Printf("create menu error:", err)
		out["status"] = MSG_ERR
		out["msg"] = err
	}
	this.jsonResult(out)

}

func (this *WXController) MenuDelete() {
	cid, err := this.GetInt64("cid")
	out := make(map[string]interface{})
	out["status"] = MSG_OK
	if err != nil {
		beego.Error("post request company id error is :%s", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = err
		this.jsonResult(out)
	}
	errMenu := menu.Delete(wechatClientMap[cid])

	if errMenu != nil {
		log.Printf("create menu error:\n%s", errMenu)
		out["status"] = MSG_ERR
		out["msg"] = errMenu
	}
	this.jsonResult(out)

}

func (this *WXController) MenuGet() {
	out := make(map[string]interface{})
	out["status"] = MSG_OK

	cid, err := this.GetInt64("cid")
	if err != nil {
		beego.Error("post request company id error is :%s", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = err
		this.jsonResult(out)
	}
	var menuResult *menu.Menu
	menuResult, _, errMenu := menu.Get(wechatClientMap[cid])

	if errMenu != nil {
		log.Printf("create menu error:\n%s", errMenu)
		out["status"] = MSG_ERR
		out["msg"] = errMenu
	} else {
		out["menu"] = menuResult
	}
	this.jsonResult(out)
}

func (this *WXController) AddNews() {
	out := make(map[string]interface{})
	out["status"] = MSG_OK
	cid, err := this.GetInt64("cid")
	if err != nil {
		beego.Error("post request company id ", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = err
		this.jsonResult(out)
	}

	o := orm.NewOrm()
	var maps []orm.Params
	_, errOrm := o.QueryTable("article").Filter("CompanyId", cid).Filter("IsValid__exact", "1").Filter("IsNews__exact", "1").Filter("MediaId", "").OrderBy("Order", "-Id").Limit(10).Values(&maps, "Title", "Desc", "ThumbPath", "Id", "MapImg", "Content")
	if errOrm != nil {
		beego.Error(errOrm.Error())
		this.StopRun()
	}
	if len(maps) == 0 {
		beego.Error("article is null")
		out["status"] = MSG_ERR
		out["msg"] = "article is null"
		this.jsonResult(out)
	}
	articles := []material.Article{}
	for _, m := range maps {
		content := m["Content"].(string)
		imgJson := m["MapImg"].(string)
		//替换文中图片地址为微信图片地址
		if imgJson != "" {
			var imgs Imgslice
			errJson := json.Unmarshal([]byte(imgJson), &imgs)
			if errJson != nil {
				beego.Error("map imgs json decode error : %s", errJson.Error())
				out["status"] = MSG_ERR
				out["msg"] = errJson
				this.jsonResult(out)
			}
			for _, v := range imgs.Imgs {
				imgSrc := v.Url
				_, imgWXSrc, errImg := Upload(v.Filepath, cid)
				if errImg != nil {
					beego.Error("img upload error :%s", errImg.Error())
					out["status"] = MSG_ERR
					out["msg"] = errImg
					this.jsonResult(out)
				}
				content = strings.Replace(content, imgSrc, imgWXSrc, -1)
			}
		}
		//替换缩略图
		thumb := m["ThumbPath"].(string)
		thumbMediaId, _, errThumb := Upload(thumb, cid)
		if errThumb != nil {
			beego.Error("thumb img upload error :%s", errThumb.Error())
			out["status"] = MSG_ERR
			out["msg"] = errThumb
			this.jsonResult(out)
		}
		//组装消息
		title := m["Title"].(string)
		desc := m["Desc"].(string)
		article := material.Article{ThumbMediaId: thumbMediaId, Title: title, Digest: desc, Content: content, ShowCoverPic: 0}
		articles = append(articles, article)

	}
	news := material.News{Articles: articles}
	newsId, errNews := material.AddNews(wechatClientMap[cid], &news)
	if errNews != nil {
		beego.Error("add news error :%s", errNews.Error())
		out["status"] = MSG_ERR
		out["msg"] = errNews
		this.jsonResult(out)
	}

	for _, m := range maps {
		_, errSql := o.QueryTable("article").Filter("Id", strconv.Itoa(int(m["Id"].(int64)))).Update(orm.Params{"MediaId": newsId})
		if errSql != nil {
			beego.Error("update article media id error :%s", errSql.Error())
		}
	}

	isPreview := this.GetString("ispreview")
	if isPreview != "" && isPreview == "ok" {
		errPreview := previewMyNews(newsId, cid)
		if errPreview != nil {
			beego.Error("preview error:%s", errPreview.Error())
			out["status"] = MSG_ERR
			out["msg"] = errPreview
			this.jsonResult(out)
		}

	} else {
		task_id, errSend := send(newsId, cid)
		if errSend != nil {
			beego.Error("send news error :%s", errSend.Error())
			out["status"] = MSG_ERR
			out["msg"] = errSend
			this.jsonResult(out)
		}
		for _, m := range maps {
			_, errSql := o.QueryTable("article").Filter("Id", strconv.Itoa(int(m["Id"].(int64)))).Update(orm.Params{"TaskId": task_id})
			if errSql != nil {
				beego.Error("update article task id error :%s", errSql.Error())
			}
		}

	}

	out["media_id"] = newsId
	this.jsonResult(out)

}

func Upload(filePath string, cid int64) (string, string, error) {
	_, err := os.Stat(filePath)
	if err != nil {
		beego.Error("file doesn't exists:%s", filePath)
		return "", "", err
	}
	media_id, url, err := material.UploadImage(wechatClientMap[cid], filePath)
	return media_id, url, err
}

func send(mediaId string, cid int64) (string, error) {
	var rsl *mass.Result
	msg := mass2all.NewNews(mediaId)
	rsl, err := mass2all.Send(wechatClientMap[cid], msg)
	task_id := strconv.FormatInt(rsl.MsgId, 10)
	return task_id, err
}
func previewMyNews(mediaId string, cid int64) error {
	var news *preview.News
	wxTestUser := beego.AppConfig.String("wxTestUser")

	news = preview.NewNews(wxTestUser, mediaId) //YKJpdCRA6KGpf2APqjUCkiyhEnE51x73gqptXwMvTCQ
	return preview.Send(wechatClientMap[cid], news)
}
func (this *WXController) UpdateNews() {
	out := make(map[string]interface{})
	out["status"] = MSG_OK
	cid, err := this.GetInt64("cid")
	if err != nil {
		beego.Error("post request company id error is :%s", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = err
		this.jsonResult(out)
	}
	o := orm.NewOrm()
	var maps []orm.Params
	_, errS := o.QueryTable("article").Filter("IsValid__exact", "1").Filter("IsNews__exact", "1").Filter("IsUpdate", "1").OrderBy("-Id").Limit(1).Values(&maps, "Title", "Desc", "ThumbPath", "Id", "MapImg", "Content", "Order", "MediaId")
	if errS != nil {
		beego.Error("query sql error:", errS.Error())
		this.StopRun()
	}

	for _, m := range maps {
		content := m["Content"].(string)
		imgJson := m["MapImg"].(string)
		order := m["Order"].(string)
		mediaId := m["MediaId"].(string)
		if len(order) == 0 || len(mediaId) == 0 {
			out["status"] = MSG_ERR
			out["msg"] = "article's order or media id  is null"
			this.jsonResult(out)
		}
		orderIndex, _ := strconv.Atoi(order)

		//替换文中图片地址为微信图片地址
		if imgJson != "" {
			var imgs Imgslice
			errJson := json.Unmarshal([]byte(imgJson), &imgs)
			if errJson != nil {
				beego.Error("map imgs json decode error : %s", errJson.Error())
				out["status"] = MSG_ERR
				out["msg"] = errJson
				this.jsonResult(out)
			}
			for _, v := range imgs.Imgs {
				imgSrc := v.Url
				_, imgWXSrc, errImg := Upload(v.Filepath, cid)
				if errImg != nil {
					beego.Error("img upload error :%s", errImg.Error())
					out["status"] = MSG_ERR
					out["msg"] = errImg
					this.jsonResult(out)
				}
				content = strings.Replace(content, imgSrc, imgWXSrc, -1)
			}
		}
		//替换缩略图
		thumb := m["ThumbPath"].(string)
		thumbMediaId, _, errThumb := Upload(thumb, cid)
		if errThumb != nil {
			beego.Error("thumb img upload error :%s", errThumb.Error())
			out["status"] = MSG_ERR
			out["msg"] = errThumb
			this.jsonResult(out)
		}
		//组装消息
		title := m["Title"].(string)
		desc := m["Desc"].(string)
		article := material.Article{ThumbMediaId: thumbMediaId, Title: title, Digest: desc, Content: content, ShowCoverPic: 0}
		err := material.UpdateNews(wechatClientMap[cid], mediaId, orderIndex, &article)
		if err != nil {
			beego.Error("update article error : ", err.Error())
			out["status"] = MSG_ERR
			out["msg"] = err
			this.jsonResult(out)
			this.StopRun()
		}
		_, errSqlUpdate := o.QueryTable("article").Filter("Id", strconv.Itoa(int(m["Id"].(int64)))).Update(orm.Params{"IsUpdate": "0"})
		if errSqlUpdate != nil {
			beego.Error("update article is_update error :%s", errSqlUpdate.Error())
		}

	}
	this.jsonResult(out)

}

func (this *WXController) GetNews() {
	out := make(map[string]interface{})
	out["status"] = MSG_OK
	cid, err := this.GetInt64("cid")
	if err != nil {
		beego.Error("post request company id error is :%s", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = err
		this.jsonResult(out)
	}
	rslt, err := material.BatchGetNews(wechatClientMap[cid], 0, 20)
	if err != nil {
		out["msg"] = err
		this.jsonResult(out)
	}
	out["msg"] = *rslt
	this.jsonResult(out)
}

func (this *WXController) UploadImage() {
	filePath := "material/makefile.png"
	out := make(map[string]interface{})
	out["status"] = MSG_OK
	cid, err := this.GetInt64("cid")
	if err != nil {
		beego.Error("post request company id error is :%s", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = err
		this.jsonResult(out)
	}
	media_id, url, err := material.UploadImage(wechatClientMap[cid], filePath)

	if err != nil {
		log.Printf("create news error:\n%s", err)
		out["status"] = MSG_ERR
		out["msg"] = err
	} else {
		out["media_id"] = media_id
		out["url"] = url
	}

	this.jsonResult(out)
}

func (this *WXController) UploadThumb() {
	filePath := "material/makefile.png"
	out := make(map[string]interface{})
	out["status"] = MSG_OK
	cid, err := this.GetInt64("cid")
	if err != nil {
		beego.Error("post request company id error is :%s", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = err
		this.jsonResult(out)
	}
	media_id, url, err := material.UploadThumb(wechatClientMap[cid], filePath)

	if err != nil {
		log.Printf("create news error:\n%s", err)
		out["status"] = MSG_ERR
		out["msg"] = err
	} else {
		out["media_id"] = media_id
		out["url"] = url
	}

	this.jsonResult(out)
}

func (this *WXController) SendGroupNews() {
	out := make(map[string]interface{})
	out["status"] = MSG_OK
	cid, err := this.GetInt64("cid")
	if err != nil {
		beego.Error("post request company id error is :%s", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = err
		this.jsonResult(out)
	}
	var rsl *mass.Result
	msg := mass2all.NewNews("YKJpdCRA6KGpf2APqjUCkoJj5m48yZ0pxFo8GLRysT4")
	rsl, errSend := mass2all.Send(wechatClientMap[cid], msg)

	if errSend != nil {
		log.Printf("create news error:\n%s", errSend)
		out["status"] = MSG_ERR
		out["msg"] = errSend
	} else {
		out["msg_id"] = rsl.MsgId
		out["msg_data_id"] = rsl.MsgDataId
	}

	this.jsonResult(out)
}

func (this *WXController) PreviewNews() {
	cid, err := this.GetInt64("cid")
	out := make(map[string]interface{})
	out["status"] = MSG_OK
	if err != nil {
		beego.Error("post request company id error is :%s", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = err
		this.jsonResult(out)
	}
	mId := this.GetString("media_id")
	var news *preview.News
	wxTestUser := beego.AppConfig.String("wxTestUser")

	news = preview.NewNews(wxTestUser, mId) //YKJpdCRA6KGpf2APqjUCkiyhEnE51x73gqptXwMvTCQ
	errSend := preview.Send(wechatClientMap[cid], news)

	if errSend != nil {
		log.Printf("create news error:\n%s", errSend)
		out["status"] = MSG_ERR
		out["msg"] = errSend
	}

	this.jsonResult(out)

}
func (this *WXController) DeleteMedia() {
	out := make(map[string]interface{})
	out["status"] = MSG_OK
	cid, err := this.GetInt64("cid")
	if err != nil {
		beego.Error("post request company id error is :%s", err.Error())
		out["status"] = MSG_ERR
		out["msg"] = err
		this.jsonResult(out)
	}

	mediaId := this.GetString("media_id")
	if mediaId == "" {
		out["status"] = MSG_ERR
		out["msg"] = "media_id is null"
		this.jsonResult(out)
	}
	errDelete := material.Delete(wechatClientMap[cid], mediaId)
	if errDelete != nil {
		out["status"] = MSG_ERR
		out["msg"] = errDelete
	}
	this.jsonResult(out)
}
